/**
作者：李科笠
2018年1月18日 15:48:25

说明  批量下载API的Proto文件
*/
package main

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
)

var targeUrl string = "https://api.***.com/api/v1/doc"

func main() {
	var (
		output   = flag.String("output", "output/", "Proto File storage location for downloaded")
		platform = flag.String("platform", "dic", "Input Target Platform, eg: hotel, company, dic")
	)

	flag.Usage = func() {}
	flag.Parse()

	if flag.NFlag() == 0 {
		fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
		flag.PrintDefaults()
		os.Exit(0)
	}

	jsonModel := httpPost()
	fmt.Fprintf(os.Stderr, "Api Doc Version: %s \n", jsonModel.Version)
	os.MkdirAll(*output+*platform, 0711)

	outputDic := *output + *platform + "/"
	switch *platform {
	case "hotel":
		group := jsonModel.APIGroups[0]
		fmt.Println(group.GroupName)
		whileProto(outputDic, group.DAPIInfo)
		break
	case "company":
		group := jsonModel.APIGroups[2]
		fmt.Println(group.GroupName)
		whileProto(outputDic, group.DAPIInfo)
		break
	case "dic":
		group := jsonModel.APIGroups[1]
		fmt.Println(group.GroupName)
		whileProto(outputDic, group.DAPIInfo)
		break
	default:
		fmt.Fprintf(os.Stderr, "no find platform type :%s \n", *platform)
		os.Exit(0)
		break
	}
}

func httpPost() (jsonModel *AutoGenerated) {
	resp, err := http.Post(targeUrl,
		"application/json", nil)
	if err != nil {
		fmt.Println(err)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err)
	}

	body = bytes.TrimPrefix([]byte(string(body)), []byte("\xef\xbb\xbf"))
	if err := json.Unmarshal(body, &jsonModel); err != nil {
		fmt.Fprintln(os.Stderr, err.Error())
		os.Exit(1)
	}

	return
}

func whileProto(output string, apigroup []DAPIInfo) {
	for _, x := range apigroup {
		writeFile(output, x.Request.ClassName+".proto", x.RequestProto)
		writeFile(output, x.Response.ClassName+".proto", x.ResponseProto)
	}
}

func writeFile(dicname string, filename string, writeString string) {
	var (
		f   *os.File
		err error
	)

	if f, err = os.OpenFile(dicname+filename, os.O_CREATE, 0666); err != nil {
		fmt.Fprintln(os.Stderr, "create file err: %v", err)
	}
	defer f.Close()
	if _, err = f.WriteString(writeString); err != nil {
		fmt.Fprintln(os.Stderr, "create file err: %v", err)
	}
	f.Sync()
}

type AutoGenerated struct {
	APIName   string      `json:"ApiName"`
	Version   string      `json:"Version"`
	Copyright string      `json:"Copyright"`
	APIGroups []APIGroups `json:"ApiGroups"`
}

type APIGroups struct {
	GroupName string     `json:"GroupName"`
	DAPIInfo  []DAPIInfo `json:"DApiInfo"`
}

type Request struct {
	UUID      string `json:"UUID"`
	ClassName string `json:"ClassName"`
	ClassDes  string `json:"ClassDes"`
}

type Response struct {
	UUID      string `json:"UUID"`
	ClassName string `json:"ClassName"`
	ClassDes  string `json:"ClassDes"`
}

type DAPIInfo struct {
	UUID          string   `json:"UUID"`
	URL           string   `json:"Url"`
	APIName       string   `json:"ApiName"`
	APIDesc       string   `json:"ApiDesc"`
	Request       Request  `json:"Request"`
	RequestProto  string   `json:"RequestProto"`
	Response      Response `json:"Response"`
	ResponseProto string   `json:"ResponseProto"`
}
